﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Aspects;
using System.Diagnostics;
using System.Collections;

namespace AOP
{
    [Serializable]
    public sealed class MethodTraceAttribute : OnMethodBoundaryAspect
    {
        //private Hashtable _watchers = Hashtable.Synchronized(new Hashtable());

        private readonly string _category;
        public string Category { get { return _category; } } 

        public MethodTraceAttribute(string category)
        {
            this._category = category;
        }

        public override void OnEntry(MethodExecutionArgs args)
        {
            Stopwatch watcher = new Stopwatch();
            watcher.Start();
            args.MethodExecutionTag = watcher;
            //Trace.WriteLine(string.Format("Entering {0}.{1}.",
              //  args.Method.DeclaringType.FullName, args.Method.Name), this._category);
        }

        public override void OnExit(MethodExecutionArgs args)
        {
            Stopwatch watcher = args.MethodExecutionTag as Stopwatch;
            if (watcher != null)
            {
                watcher.Stop();
                Trace.WriteLine(string.Format("{0},{1},{2},{3}",
                    DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
                    args.Method.DeclaringType.FullName, 
                    args.Method.Name, 
                    watcher.Elapsed.TotalMilliseconds), this._category);
            }
            else
            {
                Trace.WriteLine(string.Format("{0},{1},{2}",
                    DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
                    args.Method.DeclaringType.FullName,
                    args.Method.Name), this._category);
            }
        }
    }
}
